
import * as React from 'react';
import * as ReactDOM from 'react-dom';

import { createStore, TStore } from './createStore'
import { observable } from "mobx"
import { useLocalStore, observer } from 'mobx-react' // 6.x or mobx-react-lite@1.4.0

const TStoreContext = React.createContext<TStore>(null)

export const useStore = (): TStore => {
    const store = React.useContext(TStoreContext)
    if (!store)
        // this is especially useful in TypeScript so you don't need to be checking for null all the time
        throw new Error('useStore must be used within a StoreProvider.')
    return store
}

export const TStoreProvider = ({ children }) => {
    const store = useLocalStore(createStore)
    return <TStoreContext.Provider value={store}>{children}</TStoreContext.Provider>
}

@observer
export class C extends React.Component<{}, {}, {}>{
    declare context: React.ContextType<typeof TStoreContext>
    static contextType = TStoreContext;
    render() {
        return (
            <div>
                <button
                    onClick={() => {
                        this.context.makeFriend("test" + this.context.friends.length)
                    }}
                >Test</button>
                {this.context.friends.map(f => <div>{f.name}</div>)}
            </div>
        )
    }
}

const F = observer(() => {
    const store: TStore = useStore()
    return (
        <div>
            <button
                onClick={() => {
                    store.makeFriend("test" + store.friends.length)
                }}
            >Test</button>
            {store.friends.map(f => <div>{f.name}</div>)}
        </div>
    )
})

function App() {
    return <>
        <TStoreProvider>
            <C />
            <F />
        </TStoreProvider>
        <TStoreContext.Provider value={observable(createStore())}>
            <C />
            <F />
        </TStoreContext.Provider>
    </>
}

export function R() {
    ReactDOM.render(<App />, document.getElementById("app"))
}
